﻿using MaxStoreErp.Core.Commands;
using MaxStoreErp.Core.Interfaces;
using MaxStoreErp.Core.Threading;
using Microsoft.Practices.Unity;
using System;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace MaxStoreErp.Core.BaseClasses
{
    public class PresenterBase<TView, TViewModel> : DocumentPresenterBase
        where TView : Control, IView, new()
        where TViewModel : ViewModelBase, new()
    {
        [Dependency]
        public IUnityContainer Container { get; set; }

        [Dependency]
        public ILogger Logger { get; set; }

        [Dependency]
        public IMessager UserMessage { get; set; }

        TView _view;
        TViewModel _viewModel;

        protected PresenterBase()
        {
            ViewModel = CreateViewModel();
            View = CreateView();
            InitializeCommands();
        }

        protected PresenterBase(string headerText)
            : this()
        {
            ViewModel.Header = headerText;
        }

        void InitializeCommands()
        {
            ViewModel.ReloadViewModelData = new RelayCommand(LoadDataAsync, () => !ViewModel.IsBusy);
        }

        public TViewModel ViewModel
        {
            get { return _viewModel; }
            private set
            {
                _viewModel = value;
                OnViewModelSet();
            }
        }

        public TView View
        {
            get { return _view; }
            private set
            {
                _view = value;
                _view.Presenter = this;
                OnViewSet();
            }
        }

        /// <summary>
        /// Вызывается при установке ViewModel
        /// </summary>
        protected virtual void OnViewModelSet()
        {
        }

        /// <summary>
        /// Вызывается при установке View
        /// </summary>
        protected virtual void OnViewSet()
        {
            View.DataContext = ViewModel;
        }

        static TView CreateView()
        {
            return new TView();
        }

        static TViewModel CreateViewModel()
        {
            return new TViewModel();
        }

        public async void LoadDataAsync()
        {
            try
            {
                ViewModel.IsBusy = true;
                await Task.Factory.StartNew(OnDataLoading);
                ViewModel.IsBusy = false;
            }
            catch (Exception exception)
            {
                OnLoadError(exception);
            }
        }

        /// <summary>
        /// Вызывается при загрузке данных для ViewModel
        /// </summary>
        protected virtual void OnDataLoading()
        {
           
        }

        /// <summary>
        /// Вызывается при ошибке загрузки данных формы
        /// </summary>
        protected virtual void OnLoadError(Exception exception)
        {

        }

        protected void LogAndShowError(string message, Exception exception)
        {
            ThreadHelper.SafeCall(() =>
            {
                var text = string.Format("{0}. {1}", message, exception.Message);
                Logger.LogError(exception, text);
                UserMessage.InfoMessageAsync(text, "Ошибка выполнения");
            });
        }

        public override IView GetDocumentView(bool reloadData = true)
        {
            if (reloadData)
                LoadDataAsync();

            return View;
        }
    }
}
